<template>
	<el-drawer v-model="drawerVisible" append-to-body destroy-on-close :title="title" :size="size">
		<div v-loading="loading">
			<CForm
				v-if="drawerVisible && !loading"
				ref="cFormRef"
				v-model="formData"
				:itemList="itemList"
				:labelWidth="labelWidth"
				:labelSuffix="labelSuffix"
				:apiSubmit="apiSubmit"
				@loading-change="loadingChange"
				@submit-loading-change="submitLoadingChange"
				@submit-success="onSubmitSuccess"
			>
				<!-- 递归传递插槽！！！ -->
				<template v-for="slotName in Object.keys($slots)" #[slotName]="scope">
					<slot :name="slotName" v-bind="scope" />
				</template>
			</CForm>
		</div>

		<template #footer>
			<div>
				<el-button @click="drawerVisible = false">取消</el-button>
				<el-button :disabled="loading" type="primary" :loading="submitLoading" @click="handleSubmit">确定</el-button>
			</div>
		</template>
	</el-drawer>
</template>

<script setup lang="ts" name="CFormDrawer">
import { computed, ref } from 'vue'
import { FormItemProps } from '@/components/CForm/interface'
import CForm from '@/components/CForm/index.vue'
import { deepClone } from '@/utils/util'
import { nextTick } from 'vue'
const emits = defineEmits(['submitSuccess'])
interface DrawerProps {
	title: string // 标题
	size?: string | number // Drawer 窗体的大小
	/* 表单需要的字段 */
	itemList: FormItemProps[] // 配置项目列表
	labelWidth?: string // label 宽度
	labelSuffix?: string // 表单域标签的后缀
	apiSubmit: (...params: any[]) => Promise<any> // 提交 api
}
// 默认值
withDefaults(defineProps<DrawerProps>(), {
	labelWidth: '120px',
	size: '500px'
})
// 表单数据
const formData = ref<Record<string, any>>({})

// drawer框状态
const drawerVisible = ref(false)

const cFormRef = ref<InstanceType<typeof CForm>>()
// 获取 CForm 组件
function getCFormRef() {
	return cFormRef.value
}

// CForm 加载
const apiLoading = ref(false)
const formLoading = ref(false)
const loading = computed(() => apiLoading.value || formLoading.value)
function loadingChange(val: boolean) {
	formLoading.value = val
}

// 提交加载
const submitLoading = ref(false)
function submitLoadingChange(val: boolean) {
	submitLoading.value = val
}
// 提交成功
function onSubmitSuccess(res: any) {
	drawerVisible.value = false
	emits('submitSuccess', res)
}

// 提交数据（新增/编辑）
function handleSubmit() {
	getCFormRef()!.submit()
}

/**
 *
 */
function open(): void {
	apiLoading.value = false
	formLoading.value = false
	submitLoading.value = false

	formData.value = {}
	drawerVisible.value = true
}

/**
 * 打开，并根据参数初始化表单
 * @param data 初始表单的数据
 */
function openDataInit(data: Record<string, any> = {}): void {
	apiLoading.value = false
	formLoading.value = false
	submitLoading.value = false

	formData.value = deepClone(data)
	drawerVisible.value = true
}

/**
 * 打开，并提供初始化接口
 * @param apiInit apiInit 接口
 */
function openApiInit(apiInit: Promise<Record<string, any>>): void {
	apiLoading.value = false
	formLoading.value = false
	submitLoading.value = false

	drawerVisible.value = true
	nextTick(() => {
		apiLoading.value = true
		apiInit
			.then(data => {
				formData.value = data
			})
			.finally(() => {
				apiLoading.value = false
			})
	})
}

function getFormRef() {
	return getCFormRef()!.getFormRef()
}
defineExpose({ open, openDataInit, openApiInit, getFormRef, formData })
</script>
